package com.coolwen.springmvc.dao;/**
 * Created by CoolWen on 2017/10/28.
 */

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.Query;
import org.springframework.beans.factory.annotation.Autowired;

import java.lang.reflect.ParameterizedType;
import java.util.List;

/**
 * @author CoolWen
 * @version 2017-10-28 22:00
 */

/**
 * 可以考虑把所有公共的方法都写在baseDAo中，这个时候，让所有的DAO都继承BaseDao
 * 这样基本上就实现了大量的基础方法，如果DAO中有一些特殊的方法，再在具体的实现类的
 * DAO中创建
 * 在Spring与Hibernate4的整合中已经取消了对HibernateTemplate和HibernateDaoSupport两个类的支持
 *
 * @param <T>
 * @author Administrator
 */
public class BaseDao<T> implements IBaseDao<T> {

    @Autowired
    private SessionFactory sessionFactory;

//    @Resource(name = "sessionFactory")
//    @Autowired
//    public void setSessionFactory(SessionFactory sessionFactory) {
//        this.sessionFactory = sessionFactory;
//    }

    protected Session getSession() {
        return sessionFactory.getCurrentSession();
    }

    /**
     * 创建一个Class的对象来获取泛型的class
     */
    private Class<T> clz;

    @SuppressWarnings("unchecked")
    public Class<T> getClz() {
        if (clz == null) {
            //获取泛型的Class对象
            clz = ((Class<T>)
                    (((ParameterizedType) (this.getClass().getGenericSuperclass())).getActualTypeArguments()[0]));
        }
        return clz;
    }

    @Override
    public void add(T t) {
        this.getSession().save(t);
    }

    @Override
    public void delete(int id) {
        this.getSession().delete(this.load(id));
    }

    @Override
    public void update(T t) {
        this.getSession().update(t);
    }

    @Override
    public T load(int id) {
        return (T) this.getSession().get(getClz(), id);
    }

    @Override
    public List<T> list(String hql, Object[] args) {
        Query u = this.getSession().createQuery(hql);
        if (args != null) {
            for (int i = 0; i < args.length; i++) {
                u.setParameter(0, args[i]);
            }
        }
        List<T> list = u.list();
        return list;
    }

    @Override
    public List<T> list(String hql) {
        return this.list(hql, null);
    }

    @Override
    public List<T> list(String hql, Object arg) {
        return this.list(hql, new Object[]{arg});
    }
}
